<?php


namespace Admin\Controller;
use Admin\Model\AuthRuleModel;
use Admin\Model\AuthGroupModel;

/**
 * 权限控制器
 * Class AuthManagerController
 * @package Admin\Controller
 */
class AuthManagerController extends AdminController{

    /**分配用户组
     * @param $uid
     * @author leiying
     */
    public function groupAccess($uid){
        if(IS_POST){
            $data['group_id'] = I('post.group_id',0);
            $uid = I('post.uid');

            if($uid == 1){
                $this->error('超级管理员不用分配用户组');
            }

            $exit = M('auth_group_access')->field('uid')->where(array('uid'=>$uid))->find();
            if($exit){
                $res = M('auth_group_access')->where(array('uid'=>$uid))->save($data);
            }else{
                $data['uid'] = $uid;
                $res = M('auth_group_access')->add($data);
            }
            if(is_numeric($res)){
                $this->success('分配成功');
            }else{
                $this->error('分配失败');
            }
        }else{
            $auth_group = M('AuthGroup')
                ->field('id,title')
                ->where( array('status'=>array('egt','0'),'module'=>'admin','type'=>AuthGroupModel::TYPE_ADMIN) )
                ->select();
            $this->assign('groups',$auth_group);
            $info = M('auth_group_access')->where(array('uid'=>$uid))->find();

            $this->assign('uid',$uid);
            $this->assign('info',$info);

            $this->display();
        }
    }

    /**菜单列表
     * @author leiying
     */
    public function menuList(){
        $this->updateRules();
        $get = I('post.');
        $search_data = array();//筛选数据
        $where = array();//条件

        if(IS_POST){
            session('searchdata_menulist',$get);
        }else{
            if(I('get.p')){
                $this->assign('p',I('get.p'));
            }else{
                session('searchdata_menulist',null);
            }
            $get = $search_data = session('searchdata_menulist');
        }

        $where['is_menu'] = array('eq',1);
        $typeList = M('menu')->where($where)->order('sort')->select();
        $res =list_to_tree($typeList,'m_id');//处理成分级的嵌套数组
        //处理成一维数组
        $lists = tree_to_array($res);
        $this->assign('lists',$lists);
        $this->assign('searchs',$search_data);
        $this->display();
    }

    /**权限列表
     * @author leiying
     */
    public function authList(){
        $this->updateRules();
        if(I('jump')){
            echo "<script>parent.location.reload();</script>";exit;
        }
        $get = I('post.');
        $search_data = array();//筛选数据
        $where = array();//条件

        if(IS_POST){
            session('searchdata_menulist',$get);
        }else{
            if(I('get.p')){
                $this->assign('p',I('get.p'));
            }else{
                session('searchdata_menulist',null);
            }
            $get = $search_data = session('searchdata_menulist');
        }
        if(isset($get['is_menu']) && $get['is_menu'] != ''){
            $search_data['is_menu'] = $get['is_menu'];
            $where['is_menu'] = array('eq',$get['is_menu']);
        }

        $typeList = M('menu')->where($where)->order('sort')->select();
        $res =list_to_tree($typeList,'m_id');//处理成分级的嵌套数组
        //处理成一维数组
        $lists = tree_to_array($res);
        $this->assign('lists',$lists);
        $this->assign('searchs',$search_data);
        $this->display();
    }

    /**删除菜单
     * @author leiying
     */
    public function delMenu(){
        if(IS_POST){
            $id = I('post.id');
            //判断删除的分类是否为父级分类
            $result = M('menu')->where(array('pid'=>$id))->find();
            if($result){
                $this->error('不能删除父级分类');
            }else{
                $res = M('menu')->where(array('m_id'=>$id))->delete();
                if($res){
                    $this->success('删除成功');
                }else{
                    $this->error('删除失败');
                }
            }
        }else{
            $this->error('非法操作');
        }
    }


    /**后台节点配置的url作为规则存入auth_rule
     * 执行新节点的插入,已有节点的更新,无效规则的删除三项任务
     * @return bool
     * @author leiying
     */
    public function updateRules(){
        //需要新增的节点必然位于$nodes
        $nodes    = $this->returnNodes(false);
        $parent = array();
        foreach($nodes as $v){
            if($v['pid'] == 0){
                $parent[] = $v['id'];
            }
        }
        $AuthRule = M('AuthRule');
        $map      = array('module'=>'admin','type'=>array('in',array(1,2,3)));//status全部取出,以进行更新
        //需要更新和删除的节点必然位于$rules
        $rules    = $AuthRule->where($map)->order('name')->select();
        //构建insert数据
        $data     = array();//保存需要插入和更新的新节点
        foreach ($nodes as $value){
            $temp['name']   = $value['url'];
            $temp['title']  = $value['title'];
            $temp['module'] = 'admin';
            if($value['is_menu'] == 0){
                $temp['type'] = AuthRuleModel::RULE_URL;//动作
            }else{
                if($value['pid'] == 0){
                    $temp['type'] = AuthRuleModel::RULE_MAIN;//一级菜单
                }else{
                    $temp['type'] = AuthRuleModel::RULE_SECOND;//二级菜单
                }
            }
            $temp['icon'] = $value['icon'];//图标
            $temp['m_id'] = $value['m_id'];//菜单id
            $temp['pid'] = $value['pid'];//菜单id
            $temp['sort'] = $value['sort'];//排序
            $temp['status']   = 1;
            $data[strtolower($temp['name'].$temp['module'].$temp['type'].$temp['pid'].$temp['icon'])] = $temp;//去除重复项
        }

        $update = array();//保存需要更新的节点
        $ids    = array();//保存需要删除的节点的id

        foreach ($rules as $index=>$rule){

            $key = strtolower($rule['name'].$rule['module'].$rule['type'].$rule['pid'].$rule['icon']);
            if ( isset($data[$key]) ) {//如果数据库中的规则与配置的节点匹配,说明是需要更新的节点
                $data[$key]['id'] = $rule['id'];//为需要更新的节点补充id值
                $update[] = $data[$key];
                unset($data[$key]);
                unset($rules[$index]);
                unset($rule['condition']);
                $diff[$rule['id']]=$rule;
            }elseif($rule['status']==1){
                $ids[] = $rule['id'];
            }
        }
        if ( count($update) ) {
            foreach ($update as $k=>$row){
                if ( $row!=$diff[$row['id']] ) {
                    $AuthRule->where(array('id'=>$row['id']))->save($row);
                }
            }
        }
        if ( count($ids) ) {
            $AuthRule->where( array( 'id'=>array('IN',implode(',',$ids)) ) )->save(array('status'=>-1));
            //删除规则是否需要从每个用户组的访问授权表中移除该规则?
        }

        if( count($data) ){
            $AuthRule->addAll(array_values($data));
        }
        if ( $AuthRule->getDbError() ) {
            trace('['.__METHOD__.']:'.$AuthRule->getDbError());
            return false;
        }else{
            return true;
        }
    }


    /**
     * 权限管理首页
     * @author 朱亚杰 <zhuyajie@topthink.net>
     */
    public function index(){
        $list = $this->lists('AuthGroup',array('module'=>'admin'),'id asc');
        $list = int_to_string($list);
        $this->assign( '_list', $list );
        $this->assign( '_use_tip', true );
        $this->meta_title = '权限管理';
        $this->display();
    }

    /**
     * 创建管理员用户组
     * @author 朱亚杰 <zhuyajie@topthink.net>
     */
    public function createGroup(){
        if(I('post.btn')){$this->success('');}
        if ( empty($this->auth_group) ) {
            $this->assign('auth_group',array('title'=>null,'id'=>null,'description'=>null,'rules'=>null,));//排除notice信息
        }
        $this->meta_title = '新增用户组';
        $this->display('editgroup');
    }

    /**
     * 编辑管理员用户组
     * @author 朱亚杰 <zhuyajie@topthink.net>
     */
    public function editGroup(){
        if(I('post.btn')){$this->success('');}
        $auth_group = M('AuthGroup')->where( array('module'=>'admin','type'=>AuthGroupModel::TYPE_ADMIN) )
            ->find( (int)$_GET['id'] );
        $this->assign('auth_group',$auth_group);
        $this->meta_title = '编辑用户组';
        $this->display();
    }



    /**访问授权页面
     * @author leiying
     */
    public function access(){
        if(I('post.btn')){$this->success('');}
        $this->updateRules();
        $auth_group = M('AuthGroup')->where( array('status'=>array('egt','0'),'module'=>'admin','type'=>AuthGroupModel::TYPE_ADMIN) )
            ->getfield('id,id,title,rules');

        $node_list   = $this->returnNodes();

        $map         = array('module'=>'admin','status'=>1);
        $all_rules = M('AuthRule')->where($map)->getField('name,id');

        $this->assign('all_rules', $all_rules);

        $this->assign('node_list',  $node_list);

        $this->assign('auth_group', $auth_group);

        $this->assign('this_group', $auth_group[(int)$_GET['group_id']]);

        $this->meta_title = '访问授权';
        $this->display('managergroup');
    }

    /**
     * 管理员用户组数据写入/更新
     * @author leiying
     */
    public function writeGroup(){
        if(isset($_POST['rules'])){
            sort($_POST['rules']);
            $_POST['rules']  = implode( ',' , array_unique($_POST['rules']));
        }

        $_POST['module'] =  'admin';
        $_POST['type']   =  AuthGroupModel::TYPE_ADMIN;

        $AuthGroup       =  D('AuthGroup');
        $data = $AuthGroup->create();

        if ( $data ) {
            if ( empty($data['id']) ) {
                $r = $AuthGroup->add();
            }else{
                $r = $AuthGroup->save();
            }
            if($r===false){
                $this->error('操作失败'.$AuthGroup->getError());
            } else{
                $this->success('操作成功!',U('index'));
            }
        }else{
            $this->error('操作失败'.$AuthGroup->getError());
        }
    }


    /**
     * @param null $method
     * @author leiying
     */
    public function changeStatus($method=null){
        if ( empty($_REQUEST['id']) ) {
            $this->error('请选择要操作的数据!');
        }
        switch ( strtolower($method) ){
            case 'forbidgroup':
                $this->forbid('AuthGroup');
                break;
            case 'resumegroup':
                $this->resume('AuthGroup');
                break;
            case 'deletegroup':
                $this->delete('AuthGroup');
                break;
            default:
                $this->error($method.'参数非法');
        }
    }

    /**
     * 用户组授权用户列表
     * @author leiying
     */
    public function user($group_id){
        if(empty($group_id)){
            $this->error('参数错误');
        }

        $auth_group = M('AuthGroup')->where( array('status'=>array('egt','0'),'module'=>'admin','type'=>AuthGroupModel::TYPE_ADMIN) )
            ->getfield('id,id,title,rules');
        $prefix   = C('DB_PREFIX');
        $l_table  = $prefix.(AuthGroupModel::MEMBER);
        $r_table  = $prefix.(AuthGroupModel::AUTH_GROUP_ACCESS);
        $model    = M()->table( $l_table.' m' )->join ( $r_table.' a ON m.uid=a.uid' );
        $_REQUEST = array();
        $list = $this->lists($model,array('a.group_id'=>$group_id,'m.status'=>array('egt',0)),'m.uid asc',null,'m.uid,m.nickname,m.last_login_time,m.last_login_ip,m.status');
        int_to_string($list);
        $this->assign( '_list',     $list );
        $this->assign('auth_group', $auth_group);
        $this->assign('this_group', $auth_group[(int)$_GET['group_id']]);
        $this->meta_title = '成员授权';
        $this->display();
    }

    /**
     * 将分类添加到用户组的编辑页面
     * @author leiying
     */
    public function category(){
        $auth_group     =   M('AuthGroup')->where( array('status'=>array('egt','0'),'module'=>'admin','type'=>AuthGroupModel::TYPE_ADMIN) )
            ->getfield('id,id,title,rules');
        $group_list     =   D('Category')->getTree();
        $authed_group   =   AuthGroupModel::getCategoryOfGroup(I('group_id'));
        $this->assign('authed_group',   implode(',',(array)$authed_group));
        $this->assign('group_list',     $group_list);
        $this->assign('auth_group',     $auth_group);
        $this->assign('this_group',     $auth_group[(int)$_GET['group_id']]);
        $this->meta_title = '分类授权';
        $this->display();
    }

    public function tree($tree = null){
        $this->assign('tree', $tree);
        $this->display('tree');
    }

    /**
     * 将用户添加到用户组的编辑页面
     * @author leiying
     */
    public function group(){
        $uid            =   I('uid');
        $auth_groups    =   D('AuthGroup')->getGroups();
        $user_groups    =   AuthGroupModel::getUserGroup($uid);
        $ids = array();
        foreach ($user_groups as $value){
            $ids[]      =   $value['group_id'];
        }
        $nickname       =   D('Member')->getNickName($uid);
        $this->assign('nickname',   $nickname);
        $this->assign('auth_groups',$auth_groups);
        $this->assign('user_groups',implode(',',$ids));
        $this->display();
    }

    /**
     * 将用户添加到用户组,入参uid,group_id
     * @author leiying
     */
    public function addToGroup(){
        $uid = I('uid');
        $gid = I('group_id');
        if( empty($uid) ){
            $this->error('参数有误');
        }
        $AuthGroup = D('AuthGroup');
        if(is_numeric($uid)){
            if ( is_administrator($uid) ) {
                $this->error('该用户为超级管理员');
            }
            if( !M('Member')->where(array('uid'=>$uid))->find() ){
                $this->error('管理员用户不存在');
            }
        }

        if( $gid && !$AuthGroup->checkGroupId($gid)){
            $this->error($AuthGroup->error);
        }
        if ( $AuthGroup->addToGroup($uid,$gid) ){
            $this->success('操作成功');
        }else{
            $this->error($AuthGroup->getError());
        }
    }

    /**
     * 将用户从用户组中移除  入参:uid,group_id
     * @author leiying
     */
    public function removeFromGroup(){
        $uid = I('uid');
        $gid = I('group_id');
        if( $uid==UID ){
            $this->error('不允许解除自身授权');
        }
        if( empty($uid) || empty($gid) ){
            $this->error('参数有误');
        }
        $AuthGroup = D('AuthGroup');
        if( !$AuthGroup->find($gid)){
            $this->error('用户组不存在');
        }
        if ( $AuthGroup->removeFromGroup($uid,$gid) ){
            $this->success('操作成功');
        }else{
            $this->error('操作失败');
        }
    }

    /**
     * 将分类添加到用户组  入参:cid,group_id
     * @author leiying
     */
    public function addToCategory(){
        $cid = I('cid');
        $gid = I('group_id');
        if( empty($gid) ){
            $this->error('参数有误');
        }
        $AuthGroup = D('AuthGroup');
        if( !$AuthGroup->find($gid)){
            $this->error('用户组不存在');
        }
        if( $cid && !$AuthGroup->checkCategoryId($cid)){
            $this->error($AuthGroup->error);
        }
        if ( $AuthGroup->addToCategory($gid,$cid) ){
            $this->success('操作成功');
        }else{
            $this->error('操作失败');
        }
    }

    /**
     * 将模型添加到用户组  入参:mid,group_id
     * @author leiying
     */
    public function addToModel(){
        $mid = I('id');
        $gid = I('get.group_id');
        if( empty($gid) ){
            $this->error('参数有误');
        }
        $AuthGroup = D('AuthGroup');
        if( !$AuthGroup->find($gid)){
            $this->error('用户组不存在');
        }
        if( $mid && !$AuthGroup->checkModelId($mid)){
            $this->error($AuthGroup->error);
        }
        if ( $AuthGroup->addToModel($gid,$mid) ){
            $this->success('操作成功');
        }else{
            $this->error('操作失败');
        }
    }

}
